#include <iostream>
#include <string>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#define SIP_PORT 5060
#define BUF_SIZE 4096

std::string create_invite_request(const std::string& to, const std::string& from, const std::string& call_id) {
    return "INVITE sip:" + to + " SIP/2.0\r\n"
           "Via: SIP/2.0/UDP 127.0.0.1:" + std::to_string(SIP_PORT) + ";branch=z9hG4bK123456\r\n"
           "Max-Forwards: 70\r\n"
           "To: <sip:" + to + ">\r\n"
           "From: Alice <sip:" + from + ">;tag=7654321\r\n"
           "Call-ID: " + call_id + "\r\n"
           "CSeq: 1 INVITE\r\n"
           "Content-Type: application/sdp\r\n"
           "Content-Length: 147\r\n\r\n"
           "v=0\r\n"
           "o=Alice 2890844526 2890842807 IN IP4 127.0.0.1\r\n"
           "s=Session SDP\r\n"
           "c=IN IP4 127.0.0.1\r\n"
           "t=0 0\r\n"
           "m=audio 3456 RTP/AVP 0\r\n"
           "a=rtpmap:0 PCMU/8000\r\n";
}

int main() {
    int sockfd;
    struct sockaddr_in server_addr;
    char buffer[BUF_SIZE];

    // Create UDP socket
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        std::cerr << "Socket creation failed!" << std::endl;
        return -1;
    }

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SIP_PORT);
    inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);

    std::string invite = create_invite_request("bob@127.0.0.1", "alice@127.0.0.1", "call12345");

    // Send INVITE request
    sendto(sockfd, invite.c_str(), invite.size(), 0,
           (struct sockaddr*)&server_addr, sizeof(server_addr));

    std::cout << "Sent SIP INVITE request." << std::endl;

    // Receive response
    socklen_t addr_len = sizeof(server_addr);
    ssize_t recv_len = recvfrom(sockfd, buffer, BUF_SIZE, 0,
                                (struct sockaddr*)&server_addr, &addr_len);

    if (recv_len > 0) {
        buffer[recv_len] = '\0';
        std::cout << "Received SIP response:\n" << buffer << std::endl;
    } else {
        std::cerr << "No response received." << std::endl;
    }

    close(sockfd);
    return 0;
}